
import mxgraph from 'pages/mxgraph/graph/index';

const {
  mxEvent,
  mxUtils,
  mxRubberband,
  mxRectangle
} = mxgraph;

/**
 * 启动多选,增加判断如果点击的cell deep===0也可以启动拖拽多选
 * @param {*} sender 
 * @param {*} me 
 */
mxRubberband.prototype.mouseDown = function(sender, me)
{
  //// console.log(sender, me);
  //// console.log(!me.isConsumed(), this.isEnabled(), this.graph.isEnabled(), me.getState() == null, !mxEvent.isMultiTouchEvent(me.getEvent()));

  //// 如果点击的cell.deep===0也启动拖拽多选
  const cellState = me.getState();
  const cell = cellState && cellState.cell;
  const deep = cell && cell.deep;
  if ((deep === 0 || (!me.isConsumed() &&	me.getState() == null)) && this.isEnabled() && this.graph.isEnabled() && !mxEvent.isMultiTouchEvent(me.getEvent())){
    let offset = mxUtils.getOffset(this.graph.container);
    let origin = mxUtils.getScrollOrigin(this.graph.container);
    origin.x -= offset.x;
    origin.y -= offset.y;  
    this.start(me.getX() + origin.x, me.getY() + origin.y);

    //// Does not prevent the default for this event so that the
    //// event processing chain is still executed even if we start
    //// rubberbanding. This is required eg. in ExtJs to hide the
    //// current context menu. In mouseMove we'll make sure we're
    //// not selecting anything while we're rubberbanding.
    me.consume(false);
  }
};

mxRubberband.prototype.mouseUp = function (sender, me) {
  let execute = this.div != null && this.div.style.display != "none";
  let x0 = null;
  let y0 = null;
  let dx = null;
  let dy = null;
  if (
    this.first != null &&
    this.currentX != null &&
    this.currentY != null
  ) {
    x0 = this.first.x;
    y0 = this.first.y;
    dx = (this.currentX - x0) / this.graph.view.scale;
    dy = (this.currentY - y0) / this.graph.view.scale;
    if (!mxEvent.isAltDown(me.getEvent())) {
      dx = this.graph.snap(dx);
      dy = this.graph.snap(dy);
      if (!this.graph.isGridEnabled()) {
        if (Math.abs(dx) < this.graph.tolerance) {
          dx = 0;
        }
        if (Math.abs(dy) < this.graph.tolerance) {
          dy = 0;
        }
      }
    }
  }
  this.reset();
  if (execute) {
    if (
      mxEvent.isAltDown(me.getEvent()) &&
      this.graph.isToggleEvent(me.getEvent())
    ) {
      let rect = new mxRectangle(this.x, this.y, this.width, this.height);
      let cells = this.graph.getCells(
        rect.x,
        rect.y,
        rect.width,
        rect.height
      );
      this.graph.removeSelectionCells(cells);
    } else if (this.isSpaceEvent(me)) {
      this.graph.model.beginUpdate();
      try {
        let cells = this.graph.getCellsBeyond(
          x0,
          y0,
          this.graph.getDefaultParent(),
          true,
          true
        );
        for (let i = 0; i < cells.length; i++) {
          if (this.graph.isCellMovable(cells[i])) {
            let tmp = this.graph.view.getState(cells[i]);
            let geo = this.graph.getCellGeometry(cells[i]);

            if (tmp != null && geo != null) {
              geo = geo.clone();
              geo.translate(dx, dy);
              this.graph.model.setGeometry(cells[i], geo);
            }
          }
        }
      } finally {
        this.graph.model.endUpdate();
      }
    } else {
      let rect = new mxRectangle(this.x, this.y, this.width, this.height);
      this.graph.selectRegion(rect, me.getEvent());
    }
    me.consume();
  }
};

mxRubberband.prototype.isSpaceEvent = function (me) {
  return (
    this.graph.isEnabled() &&
		!this.graph.isCellLocked(this.graph.getDefaultParent()) &&
		mxEvent.isControlDown(me.getEvent()) &&
		mxEvent.isShiftDown(me.getEvent())
  );
};

//// Handles preview for creating/removing space in diagram
mxRubberband.prototype.mouseMove = function (sender, me) {
  if (!me.isConsumed() && this.first != null) {
    let origin = mxUtils.getScrollOrigin(this.graph.container);
    let offset = mxUtils.getOffset(this.graph.container);
    origin.x -= offset.x;
    origin.y -= offset.y;
    let x = me.getX() + origin.x;
    let y = me.getY() + origin.y;
    let dx = this.first.x - x;
    let dy = this.first.y - y;
    let tol = this.graph.tolerance;

    if (this.div != null || Math.abs(dx) > tol || Math.abs(dy) > tol) {
      if (this.div == null) {
        this.div = this.createShape();
      }

      //// Clears selection while rubberbanding. This is required because
      //// the event is not consumed in mouseDown.
      mxUtils.clearSelection();
      this.update(x, y);

      if (this.isSpaceEvent(me)) {
        let right = this.x + this.width;
        let bottom = this.y + this.height;
        let scale = this.graph.view.scale;

        if (!mxEvent.isAltDown(me.getEvent())) {
          this.width = this.graph.snap(this.width / scale) * scale;
          this.height = this.graph.snap(this.height / scale) * scale;

          if (!this.graph.isGridEnabled()) {
            if (this.width < this.graph.tolerance) {
              this.width = 0;
            }

            if (this.height < this.graph.tolerance) {
              this.height = 0;
            }
          }

          if (this.x < this.first.x) {
            this.x = right - this.width;
          }

          if (this.y < this.first.y) {
            this.y = bottom - this.height;
          }
        }

        this.div.style.borderStyle = "dashed";
        this.div.style.backgroundColor = "white";
        this.div.style.left = this.x + "px";
        this.div.style.top = this.y + "px";
        this.div.style.width = Math.max(0, this.width) + "px";
        this.div.style.height = this.graph.container.clientHeight + "px";
        this.div.style.borderWidth =
					this.width <= 0 ? "0px 1px 0px 0px" : "0px 1px 0px 1px";

        if (this.secondDiv == null) {
          this.secondDiv = this.div.cloneNode(true);
          this.div.parentNode.appendChild(this.secondDiv);
        }

        this.secondDiv.style.left = this.x + "px";
        this.secondDiv.style.top = this.y + "px";
        this.secondDiv.style.width =
					this.graph.container.clientWidth + "px";
        this.secondDiv.style.height = Math.max(0, this.height) + "px";
        this.secondDiv.style.borderWidth =
					this.height <= 0 ? "1px 0px 0px 0px" : "1px 0px 1px 0px";
      } else {
        //// Hides second div and restores style
        this.div.style.backgroundColor = "";
        this.div.style.borderWidth = "";
        this.div.style.borderStyle = "";

        if (this.secondDiv != null) {
          this.secondDiv.parentNode.removeChild(this.secondDiv);
          this.secondDiv = null;
        }
      }

      me.consume();
    }
  }
};

//// Removes preview
let mxRubberbandReset = mxRubberband.prototype.reset;
mxRubberband.prototype.reset = function () {
  if (this.secondDiv != null) {
    this.secondDiv.parentNode.removeChild(this.secondDiv);
    this.secondDiv = null;
  }

  mxRubberbandReset.apply(this, arguments);
};
mxRubberband.prototype.fadeOut = true;
mxRubberband.prototype.defaultOpacity = 30;
